-- GhostShip
-- Create by panyl
-- 幽灵船对象

GhostShip = {
    classId = 0,
    hp     = 0,
    mp     = 0,
    level  = 0,
    skills  = {},

    -- 对象类型为幽灵船
    type = OBJECT_TYPE_GHOST_SHIP,
};
GhostShip.__index = GhostShip;

-- 构造函数
function GhostShip.new(classId, data)
    local self = {};
    setmetatable(self, GhostShip);
    self.classId = classId;
    self.dbase = Dbase.new(data);

    for key, value in pairs(data) do
        self[key] = value;
    end

    -- 设置幽灵船的数据
    if data.level ~= nil then
        self.level = data.level
    end

    -- 如果有技能
    if data.skills ~= nil then
        self:setSkills(data.skills);
    else
        self:setSkills({});
    end

    -- 血量
    if data.hp ~= nil then
        self:setHp(data.hp);
    else
        self:setHp(FormulaM.invoke("BASE_GHOST_SHIP_HP", self));
    end

    -- 魔法值
    if data.mp ~= nil then
        self:setMp(data.mp);
    else
        self:setMp(self:getMaxMp());
    end

    return self;
end

-- 取得该对象的描述字符串
function GhostShip:get_ob_id()
    return string.format("GhostShip:%s", tostring(self.classId));
end

-- 查找数据
function GhostShip:query(path, path2, default)
    if path == "classId" or path == "class_id" then
        return self.classId;
    elseif path == "level"  then return self.level;
    else
        local v = self.dbase:query(path, path2, default);
        if v then
            return v;
        else
            return GhostShipM.query(self.classId, path);
        end
    end
end

-- 设置真正的血量（由于monster有该接口，因此这里也需要）
function GhostShip:setRealHp(hp)
    self:setHp(hp);
end

-- 是否是远程怪物，和monster保持一致
function GhostShip:isRemoteMonster()
    local arr = FormulaM.invoke("GET_ALL_REMOTE_PROPS");

    for _, alias in pairs(arr) do
        local props = PropM.fetchProps(self, alias);
        if #props > 0 then
            return true;
        end
    end
    return false;
end

-- 设置血量
function GhostShip:setHp(hp)
    local add = hp - self:getHp(false);
    local baseHp = self.dbase:query("hp", 0) + add;

    self.dbase:set("hp", baseHp);
end

-- 设置魔法值
function GhostShip:setMp(mp)
    local add = mp - self:getMp(false);
    local baseMp = self.dbase:query("mp", 0) + add;

    self.dbase:set("mp", baseMp);
end

-- 幽灵船后天技能
function GhostShip:getSkills()
    -- 所有后天学习的技能
    return self.skills;
end

-- 幽灵船所有技能
function GhostShip:getAllSkills()
    return self:getSkills();
end

-- 查询属性
function GhostShip:queryAttrib(attrib, args)
    return AttribM.queryAttrib(self, attrib, args);
end

-- 计算最大血量
function GhostShip:getMaxHp()
    return self:queryAttrib("max_hp");
end

-- 当前血量
function GhostShip:getHp()
    return self:queryAttrib("hp");
end

-- 获取魔法值
function GhostShip:getMp()
    return self:queryAttrib("mp");
end

-- 获取最大魔法值
function GhostShip:getMaxMp()
    return self:queryAttrib("max_mp");
end

-- 计算基础攻击值
function GhostShip:getAttack()
    return self:queryAttrib("attack");
end

-- 计算基础魔法值
function GhostShip:getMagic()
    return self:queryAttrib("magic");
end

-- 命中
function GhostShip:getAccuracy()
    return self:queryAttrib("accuracy");
end

-- 闪避
function GhostShip:getDodge()
    return self:queryAttrib("dodge");
end

-- 获取等级
function GhostShip:getLevel()
    return self:queryAttrib("level");
end

function GhostShip:getRank()
    return self:queryAttrib("rank");
end

-- 名称
function GhostShip:getName()
    return self:query("name");
end

-- 更新数据
function GhostShip:updateData(data)
    for key, value in pairs(data) do
        self[key] = value;
    end

    self.dbase:aborb(data);
end

-- 是否已经被雇佣了
function GhostShip:isHired()
    return self.hired == 1;
end

-- 判断是否是boss
function GhostShip:isBoss()
    return false;
end

-- 是否是冈布奥怪
function GhostShip:isSlime()
    return false;
end

-- 是否是观众怪
function GhostShip:isAudience()
    return false;
end

-- 获取属主
function GhostShip:getOwner()
    if self:isHired() then
        return ME.user;
    end
end

function GhostShip:getPos()
    return self.pos or self.dbase:query("pos");
end

-- 倒计时
function GhostShip:getCountDown()
    return GhostShipM.getAttackCountDown(self);
end

-- 受到伤害
function GhostShip:receiveDamage(damage)
    local hp = self:getHp() - damage;
    self:setHp(hp);

    local msg = string.format("[GhostShip]%s收到伤害：%d，当前hp：%d，max_hp：%d",
        self:getName(), damage, hp, self:getMaxHp());
    DungeonLogM.addLog(msg);

    -- 抛出幽灵船受创事件
    EventMgr.fire(event.GHOST_SHIP_DAMAGED, {["ship"] = self, ["damage"] = damage, ["pos"] = self:getPos(), });

    return hp;
end

-- 死亡
function GhostShip:die()
    if self:getHp() > 0 then
        return false;
    end

    DungeonLogM.addLog("[GhostShip]幽灵船死亡了。");

    -- 标记死亡
    self.dbase:set("is_dead", 1);

    -- 如果还未被雇佣
    if not self:isHired() then
        -- 尝试清怪处理
        DungeonServiceM.monsterClear();
    end

    -- 抛出事件
    EventMgr.fire(event.GHOST_SHIP_DIE);

    return true;
end

-- 是否已死亡
function GhostShip:isDead()
    -- 有死亡标志
    if 1 == self.dbase:query("is_dead") then
        return true;
    end

    return false;
end

-- 复活
function GhostShip:revive(hp, mp)
    self.dbase:delete("is_dead");

    self:setHp(self:getMaxHp());
end

-- 幽灵船是否有技能
function GhostShip:ownSkill(skillId)
    local base = SkillM.findBaseSkill(skillId);
    for _, id in pairs(self.skills) do
        if SkillM.findBaseSkill(id) == base then
            return true;
        end
    end
    return false;
end

-- 技能等级
function GhostShip:getSkillLevel(skillId)
    local base = SkillM.findBaseSkill(skillId);
    for _, id in pairs(self.skills) do
        if SkillM.findBaseSkill(id) == base then
            return SkillM.query(id, "level");
        end
    end

    return 0;
end

-- 设置等级
function GhostShip:setLevel(level)
    self.level = level;
end

-- 设置技能
function GhostShip:setSkills(skills)
    self.skills = skills;
end

-- 升级技能，这里不做检查
function GhostShip:upgradeSkill(skillId)
    local base = SkillM.findBaseSkill(skillId);
    for index, id in pairs(self.skills) do
        if SkillM.findBaseSkill(id) == base then
            local next = SkillM.query(id, "next");
            self.skills[index] = next;

            break;
        end
    end
end

-- 学习技能
function GhostShip:learnSkill(skillId)
    table.insert(self.skills, skillId);
end

-- 属性表现需要的检查
function GhostShip:checkPauseBackPerformance()
    if self:isHired() then
        -- 船怪才需要
        return;
    end

    local monster = self;

    if FormulaM.invoke("MONSTER_IS_STOPED", monster) then
        -- 时间停止
        monster.dbase:set("isPause", true);
    end

    if FormulaM.invoke("CAN_MONSTER_CHANGE_MODEL", monster) then
        -- 变形术
        if monster:isBoss() then
            monster.dbase:set("changeClassId", 1);
        else
            monster.dbase:set("changeClassId", 2);
        end
    end
end
